package com.fastloan.safe.mgt.root.service.impl;

import com.fastloan.safe.core.util.ManagerKit;
import com.fastloan.safe.mgt.root.dao.CmDefResMenuMapper;
import com.fastloan.safe.mgt.root.model.CmDefFunRes;
import com.fastloan.safe.mgt.root.model.CmDefResMenu;
import com.fastloan.safe.mgt.root.model.vo.DefMenuTreeVo;
import com.fastloan.safe.mgt.root.model.vo.DefMenuVo;
import com.fastloan.safe.mgt.root.service.CmDefFunResService;
import com.fastloan.safe.mgt.root.service.CmDefResMenuService;
import com.fastloan.safe.mgt.user.model.CmuUser;
import com.kawins.base.BaseMapper;
import com.kawins.base.baseabs.BaseServiceImpl;
import com.kawins.supers.tree.Bean2TreeUtil;
import com.kawins.util.colle.ListSortUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

/**
 * @author rankai
 *         createTime 2017-09-2017/9/28 10:48
 */
@Service
public class CmDefResMenuServiceImpl extends BaseServiceImpl<CmDefResMenu> implements CmDefResMenuService {

    @Autowired
    private CmDefResMenuMapper defMenuMapper;

    @Autowired
    private CmDefFunResService defFunResService;

    @Override
    protected BaseMapper<CmDefResMenu> buildDao() {
        return defMenuMapper;
    }

    @Override
    public List<DefMenuVo> pageListNoPage(Map<String, Object> map, String menuId, int isLast) {
        if (isLast == 0) {
            menuId = TOP_MENU_PARENT_ID;
        } else if (isLast == 1) {
            CmDefResMenu defMenu = selectByPrimaryKey(menuId);
            menuId = defMenu.getParentId();
        }
        map.put("menuId", menuId);
        return defMenuMapper.selectAllToMenuVo(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertForShort(CmDefResMenu defResMenu) {
        log.debug("新增菜单:" + defResMenu);
        defResMenu.setCreateBy(ManagerKit.getUser().getId().toString());
        defResMenu.setCreateTime(new Date());
        if (StringUtils.isBlank(defResMenu.getParentId())) {
            defResMenu.setParentId(TOP_MENU_PARENT_ID);
        }
        updateSortBatch(defResMenu.getShorts(), defResMenu.getParentId(), null, false);
        insertSelective(defResMenu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateForSort(CmDefResMenu defResMenu) {
        log.debug("更新菜单:" + defResMenu);
        defResMenu.setCreateBy(null);
        defResMenu.setCreateTime(null);
        CmDefResMenu oldDefResMenu = selectByPrimaryKey(defResMenu.getId());
        //更新排序
        if (!oldDefResMenu.getShorts().equals(defResMenu.getShorts())) {
            updateSortBatch(defResMenu.getShorts(), oldDefResMenu.getParentId(), oldDefResMenu.getShorts(), false);
            updateByPrimaryKeySelective(new CmDefResMenu().setId(oldDefResMenu.getId()).setShorts(defResMenu.getShorts()));
        } else {
            //转入上级
            if (StringUtils.isBlank(defResMenu.getParentId())) {
                CmDefResMenu cmDefResMenu = selectByPrimaryKey(defResMenu.getId());
                cmDefResMenu = selectByPrimaryKey(cmDefResMenu.getParentId());
                defResMenu.setParentId(cmDefResMenu.getParentId());
            } else {
                defResMenu.setShorts(null);
                defResMenu.setParentId(null);
            }
            updateByPrimaryKeySelective(defResMenu);
        }
    }

    @Override
    public List<DefMenuTreeVo> selectMenuListByRole() {
        CmuUser user = ManagerKit.getUser();
        List<DefMenuTreeVo> defMenuTreeVoList;
        if (StringUtils.isNotBlank(user.getRootRoleId())) {
            defMenuTreeVoList = defMenuMapper.selectMenuListForRoot(user.getRootRoleId());
        } else {
            defMenuTreeVoList = selectMenuListForAll(user.getId(), false);
        }
        LinkedHashMap<String, Integer> orderMap = new LinkedHashMap<>();
        orderMap.put("shorts", ListSortUtil.ASC);
        Bean2TreeUtil<DefMenuTreeVo> bean2TreeUtil = new Bean2TreeUtil<>(orderMap);
        return bean2TreeUtil.getChildNodesByParentId(defMenuTreeVoList, TOP_MENU_PARENT_ID);
    }

    @Override
    public List<DefMenuTreeVo> selectMenuListForAll(String userId, boolean isTree) {
        List<DefMenuTreeVo> menuListByRole = defMenuMapper.selectMenuListByRoleForAll(userId);
        List<DefMenuTreeVo> menuListByUser = defMenuMapper.selectMenuListByUserForAll(userId, true);
        List<DefMenuTreeVo> menuListByUserNoHas = defMenuMapper.selectMenuListByUserForAll(userId, false);
        HashSet<String> menuSetByRole = buildHashSet(menuListByRole);
        HashSet<String> menuSetByUser = buildHashSet(menuListByUser);
        HashSet<String> menuSetByUserNoHas = buildHashSet(menuListByUserNoHas);
        menuSetByRole.addAll(menuSetByUser);
        menuSetByRole.removeAll(menuSetByUserNoHas);
        Example example = new Example(CmDefResMenu.class);
        example.createCriteria().andIn("id", menuSetByRole);
        List<CmDefResMenu> defResMenus = selectByExample(example);
        List<DefMenuTreeVo> list = new ArrayList<>(defResMenus.size());
        for (CmDefResMenu defResMenu : defResMenus) {
            DefMenuTreeVo defMenuTreeVo = new DefMenuTreeVo();
            defMenuTreeVo.setId(defResMenu.getId());
            defMenuTreeVo.setUrl(defResMenu.getUrl());
            defMenuTreeVo.setName(defResMenu.getName());
            defMenuTreeVo.setParentId(defResMenu.getParentId());
            defMenuTreeVo.setMenuPic(defResMenu.getMenuPic());
            defMenuTreeVo.setShorts(defResMenu.getShorts());
            list.add(defMenuTreeVo);
        }
        if (isTree) {
            LinkedHashMap<String, Integer> orderMap = new LinkedHashMap<>();
            orderMap.put("shorts", ListSortUtil.ASC);
            Bean2TreeUtil<DefMenuTreeVo> bean2TreeUtil = new Bean2TreeUtil<>(orderMap);
            return bean2TreeUtil.getChildNodesByParentId(list, TOP_MENU_PARENT_ID);
        }
        return list;
    }

    private HashSet<String> buildHashSet(List<DefMenuTreeVo> defMenuTreeVos) {
        HashSet<String> hashSet = new HashSet<>(defMenuTreeVos.size());
        for (DefMenuTreeVo defMenuTreeVo : defMenuTreeVos) {
            hashSet.add(defMenuTreeVo.getId());
        }
        return hashSet;
    }

    @Override
    public List<DefMenuVo> paramForMenu(String name) {
        return defMenuMapper.paramForMenu(name);
    }

    @Override
    public List<CmDefResMenu> selectDefMenuResByFunId(String defFunId) {
        return defMenuMapper.selectDefMenuResByFunId(defFunId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(String cmDefResMenuId) {
        deleteByPrimaryKey(cmDefResMenuId);
        defFunResService.delete(new CmDefFunRes().setResId(cmDefResMenuId).setResType(1));
    }

    private void updateSortBatch(Integer shorts, String parentId, Integer oldSorts, boolean isDel) {
        Example example = new Example(CmDefResMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId", parentId);
        int impairment = 1;
        if (oldSorts == null) {
            if (isDel) {
                impairment = -1;
            }
            criteria.andGreaterThanOrEqualTo("shorts", shorts);
        } else {
            if (shorts > oldSorts) {
                criteria.andBetween("shorts", oldSorts + 1, shorts);
                impairment = -1;
            } else {
                criteria.andBetween("shorts", shorts, oldSorts - 1);
            }
        }
        List<CmDefResMenu> defResMenus = selectByExample(example);
        if (defResMenus.size() != 0) {
            for (CmDefResMenu defResMenu : defResMenus) {
                defResMenu.setShorts(defResMenu.getShorts() + impairment);
                updateByPrimaryKeySelective(defResMenu);
            }
        }
    }
}
